home *** CD-ROM | disk | FTP | other *** search
- /* run a command at certain time-of-day */
-
- #include <time.h>
- #include "global.h"
- #include "timer.h"
- #include "cmdparse.h"
-
- #if (defined(MSDOS) && !(defined(MSC)) && !(defined(__TURBOC__)))
- # define TIMEZONE 0L /* Aztec doesn't define timezone */
- #endif
-
- #ifdef UNIX
- # define TIMEZONE (daylight? altzone : timezone) /* XENIX has "altzone" */
- #endif
-
- #ifdef MWC
- # define TIMEZONE timezone /* MWC does not know "daylight" */
- #endif
-
- #ifndef TIMEZONE
- # define TIMEZONE (daylight? timezone - 3600L : timezone)
- #endif
-
- struct at
- {
- struct at *next,*prev; /* doubly-linked list */
- time_t when; /* time-of-day */
- int argc; /* description of command */
- char *argv[NARG]; /* pointers to copied args */
- };
- #define NULLAT ((struct at *) 0)
-
- struct at *at_head = NULLAT; /* list of scheduled commands */
- time_t lasttime = 0; /* last time we executed one */
-
- struct timer at_timer; /* 1-minute timer to execute cmds */
-
- static void at_tick();
-
- extern struct cmds cmds[]; /* commands */
- extern char nospace[];
-
- int
- doat (argc,argv)
- int argc;
- char *argv[];
-
- {
- register struct at *at,*new;
- char *p;
- time_t when;
- int i;
-
- if (argc < 2) {
- printf("Time Command\n");
- for (at = at_head; at != NULLAT; at = at->next){
- i = (int) (at->when / 60L);
- printf("%2d:%02d ",i / 60,i % 60);
- for (i = 0; i < at->argc; i++)
- printf(" %s",at->argv[i]);
- printf("\n");
- }
- return 0;
- }
- if ((p = index(argv[1],':')) == NULLCHAR){
- printf("Usage: at hh:mm [command]\n");
- return 1;
- }
- if ((when = 3600L * atoi(argv[1]) + 60 * atoi(p + 1)) >= 86400L){
- printf("at: illegal time\n");
- return 1;
- }
- for (at = at_head; at != NULLAT; at = at->next)
- if (at->when == when){
- for (i = 0; i < at->argc; i++)
- free(at->argv[i]);
-
- if (at->next != NULLAT)
- at->next->prev = at->prev;
-
- if (at->prev != NULLAT)
- at->prev->next = at->next;
- else
- at_head = at->next;
-
- free(at);
- break;
- }
- if (argc > 2){
- /* create new "at" control block */
- if ((new = (struct at *) calloc(1,sizeof(struct at))) == NULLAT){
- printf(nospace);
- return 1;
- }
- new->when = when;
- new->argc = argc - 2;
- /* copy command and args to allocated space and link to "at" block */
- for (i = 0; i < new->argc; i++){
- if ((new->argv[i] = malloc(strlen(argv[i + 2]) + 1)) == NULLCHAR){
- while (--i >= 0)
- free(new->argv[i]);
- free(new);
- printf(nospace);
- return 1;
- }
- strcpy(new->argv[i],argv[i + 2]);
- }
- /* find proper position in the list (sorted on time-of-day) */
- for (at = at_head; at != NULLAT; at = at->next)
- if (at->when > when)
- break;
- if (at == NULLAT){
- if (at_head == NULLAT)
- at_head = new;
- else {
- for (at = at_head; at->next != NULLAT; at = at->next)
- ; /* find end of list */
- at->next = new;
- new->prev = at;
- }
- } else { /* insert before this one */
- if ((new->prev = at->prev) != NULLAT)
- new->prev->next = new;
- else
- at_head = new;
- at->prev = new;
- new->next = at;
- }
- }
-
- stop_timer(&at_timer);
- if (at_head != NULLAT){ /* anything to run? */
- if (at_timer.start == 0){ /* first time? */
- at_timer.start = SEC2TICK(60); /* tick each minute */
- at_timer.func = at_tick;
- lasttime = (time(NULL) - TIMEZONE) % 86400L; /* init last-time-done */
- }
- start_timer(&at_timer);
- at_timer.count = SEC2TICK(60 - (time(NULL) % 60)); /* sync with minute */
- }
- return 0;
- }
-
- /* called once a minute to check for commands to run */
-
- static void
- at_tick ()
-
- {
- register struct at *at;
- time_t now;
- char *argv[NARG];
-
- at = at_head;
- now = (time(NULL) - TIMEZONE) % 86400L; /* get time of day */
-
- /* skip all commands that already have been processed */
- if (now > lasttime)
- while (at != NULLAT && at->when <= lasttime)
- at = at->next;
-
- while (at != NULLAT){
- if (at->when <= now){ /* time to run it? */
- memcpy(argv,at->argv,NARG * sizeof(char *)); /* copy arg vector */
- docmd(cmds,at->argc,argv); /* and go! */
- }
-
- at = at->next;
- }
-
- lasttime = now; /* remember last time */
- start_timer(&at_timer); /* look again in a minute */
- }
-